//////////////////////////////////////////////
// DofComplexEffect.h
//
//////////////////////////////////////////////

/// Defines / Macros -------------------------

#pragma once

/// Forward decl -----------------------------

namespace nkAstraeus
{
	class BlurComplexEffect ;
	class System ;
	class TextureCopyEffect ;
}

namespace nkGraphics
{
	class Camera ;
	class Program ;
	class Sampler ;
	class Shader ;
	class TargetOperations ;
	class Texture ;
	class Viewport ;
}

/// Includes ---------------------------------

// nkAstraeus
#include "../../../Dll/DllDefines.h"

#include "../ComplexEffect.h"

#include "DofComplexEffectInfo.h"

// nkMemory
#include <NilkinsMemory/Pointers/UniquePtr.h>

/// Class ------------------------------------

namespace nkAstraeus
{
	class DLL_ASTRAEUS_EXPORT DofComplexEffect final : public ComplexEffect
	{
		public :

			// Constructor, destructor
			DofComplexEffect (System* system) noexcept ;
			virtual ~DofComplexEffect () ;

			// Getters
			nkGraphics::Texture* getSourceTexture () const ;
			nkGraphics::Texture* getSourceDepth () const ;
			nkGraphics::Texture* getOutputTexture () const ;
			nkGraphics::Camera* getCamera () const ;
			float getNearPlaneDistance () const ;
			float getFocalPlaneDistance () const ;
			float getFocalPlaneThickness () const ;
			float getFarPlaneDistance () const ;
			unsigned int getBlurStrength () const ;
			bool getLinearDepth () const ;

			// Setters
			void setSourceTexture (nkGraphics::Texture* value) ;
			void setSourceDepth (nkGraphics::Texture* value) ;
			void setCamera (nkGraphics::Camera* value) ;
			void setNearPlaneDistance (float value) ;
			void setFocalPlaneDistance (float value) ;
			void setFocalPlaneThickness (float value) ;
			void setFarPlaneDistance (float value) ;
			void setBlurStrength (unsigned int value) ;
			void setLinearDepth (bool value) ;

			// Load
			virtual bool load () override ;
			virtual void unload () override ;

		public :

			// Statics
			static nkMemory::UniquePtr<DofComplexEffect> create (System* system = nullptr) ;

		private :

			// Functions
			// Textures
			bool _prepareTextures () ;
			bool _prepareSamplers () ;
			// Viewports
			bool _prepareViewports () ;
			// Shaders
			bool _prepareShaders () ;

			// Compositor
			bool _prepareCompositorNode () ;

		private :

			// Attributes
			System* _system ;

			// Program
			DofComplexEffectInfo _loadedInfo ;
			nkGraphics::CompositorNode* _loadedNode ;

			// Info
			DofComplexEffectInfo _info ;

			// Resources
			nkMemory::UniquePtr<nkGraphics::Shader> _downSamplingShader ;
			nkMemory::UniquePtr<BlurComplexEffect> _blurringEffectNear ;
			nkMemory::UniquePtr<BlurComplexEffect> _blurringEffectFar ;
			nkMemory::UniquePtr<BlurComplexEffect> _blurringEffectFadeInfo ;
			nkMemory::UniquePtr<nkGraphics::Shader> _blendShader ;
			nkMemory::UniquePtr<nkGraphics::Texture> _downSampledTextureNear ;
			nkMemory::UniquePtr<nkGraphics::Texture> _downSampledTextureFar ;
			nkMemory::UniquePtr<nkGraphics::Texture> _downSampledTextureFadeInfo ;
			nkMemory::UniquePtr<nkGraphics::Texture> _outputTexture ;
			nkMemory::UniquePtr<nkGraphics::Sampler> _sampler ;
			nkMemory::UniquePtr<nkGraphics::Sampler> _samplerDepth ;
			nkMemory::UniquePtr<nkGraphics::Viewport> _viewportDown ;
			nkMemory::UniquePtr<nkGraphics::Viewport> _viewportHigh ;

			nkGraphics::TargetOperations* _downSamplingOp ;
			nkGraphics::TargetOperations* _blendOp ;
	} ;
}